home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / nhclb120.zoo / pathname.c < prev    next >
C/C++ Source or Header  |  1992-06-18  |  3KB  |  126 lines

  1. #include "global.h"
  2.  
  3. /* Given a working directory and an arbitrary pathname, resolve them into
  4.  * an absolute pathname. Memory is allocated for the result, which
  5.  * the caller must free
  6.  */
  7.  
  8.  
  9. static crunch(); 
  10.  
  11.  
  12. char *
  13. pathname(cd,path)
  14. char *cd;    /* Current working directory */
  15. char *path;    /* Pathname argument */
  16. {
  17.     register char *buf;
  18. #if    (defined(MSDOS) || defined(ATARI_ST))
  19.     register char *cp;
  20.     char *cdtmp,*pathtmp;
  21. #endif
  22.  
  23.     if(cd == NULLCHAR || path == NULLCHAR)
  24.         return NULLCHAR;
  25. #if    (defined(MSDOS) || defined(ATARI_ST))
  26.     /* Make temporary copies of cd and path
  27.      * with all \'s translated to /'s
  28.     */
  29.     pathtmp = malloc((unsigned)strlen(path)+1);
  30.     strcpy(pathtmp,path);
  31.     path = pathtmp;
  32.     if((cp = path) != NULLCHAR){
  33.         while((cp = index(cp,'\\')) != NULLCHAR)
  34.             *cp = '/';
  35.     }
  36.     cdtmp = malloc((unsigned)strlen(cd)+1);
  37.     strcpy(cdtmp,cd);
  38.     cd = cdtmp;
  39.     if((cp = cd) != NULLCHAR){
  40.         while((cp = index(cp,'\\')) != NULLCHAR)
  41.             *cp = '/';
  42.     }
  43. #endif
  44.     /* Strip any leading white space on args */
  45.     while(*cd == ' ' || *cd == '\t')
  46.         cd++;
  47.     while(*path == ' ' || *path == '\t')
  48.         path++;
  49.  
  50.     /* Allocate and initialize output buffer; user must free */
  51.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  52.     buf[0] = '\0';
  53.  
  54.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  55.     if(path[0] != '/')
  56.         crunch(buf,cd);
  57.  
  58.     crunch(buf,path);
  59.  
  60.     /* Special case: null final path means the root directory */
  61.     if(buf[0] == '\0'){
  62.         buf[0] = '/';
  63.         buf[1] = '\0';
  64.     }
  65.  
  66. #if    (defined(MSDOS) || defined(ATARI_ST))
  67.     /* Translate all /'s back to \'s and free temp copies of args */
  68.     if((cp = buf) != NULLCHAR){
  69.         while((cp = index(cp,'/')) != NULLCHAR)
  70.             *cp = '\\';
  71.     }
  72.     free(cdtmp);
  73.     free(pathtmp);
  74. #endif
  75.     return buf;
  76. }
  77.  
  78. /* Process a path name string, starting with and adding to
  79.  * the existing buffer
  80.  */
  81. static
  82. crunch(buf,path)
  83. char *buf;
  84. register char *path;
  85. {
  86.     register char *cp;
  87.     
  88.  
  89.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  90.     
  91.     /* Now start crunching the pathname argument */
  92.     for(;;){
  93.         /* Strip leading /'s; one will be written later */
  94.         while(*path == '/')
  95.             path++;
  96.         if(*path == '\0')
  97.             break;        /* no more, all done */
  98.         /* Look for parent directory references, either at the end
  99.          * of the path or imbedded in it
  100.          */
  101.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  102.             /* Hop up a level */
  103.             if((cp = rindex(buf,'/')) == NULLCHAR)
  104.                 cp = buf;    /* Don't back up beyond root */
  105.             *cp = '\0';        /* In case there's another .. */
  106.             path += 2;        /* Skip ".." */
  107.             while(*path == '/')    /* Skip one or more slashes */
  108.                 path++;
  109.         /* Look for current directory references, either at the end
  110.          * of the path or imbedded in it
  111.          */
  112.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  113.             /* "no op" */
  114.             path++;            /* Skip "." */
  115.             while(*path == '/')    /* Skip one or more slashes */
  116.                 path++;
  117.         } else {
  118.             /* Ordinary name, copy up to next '/' or end of path */
  119.             *cp++ = '/';
  120.             while(*path != '/' && *path != '\0')
  121.                 *cp++ = *path++;
  122.         }
  123.     }
  124.     *cp++ = '\0';
  125. }
  126.